﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using FITClub.Episode1.Levels;
using FITClub.LevelBuilder.Helper;
using FITClub.LevelBuilder.Library;
using FITClub.TextureMenu;
using FITClub.Util;
using Microsoft.Xna.Framework.Graphics;

namespace FITClub.LevelBuilder
{
    /// <summary>
    /// Keeps together default settings model library.
    /// </summary>
    public partial class DefaultsForm : Form
    {
        public BackgroundItemConfig BackgroundItem { get { return this.backgroundItem.Clone() as BackgroundItemConfig; } }

        public PlatformConfig Platform { get { return this.platform.Clone() as PlatformConfig; } }

        public PowerUpConfig PowerUp { get { return this.powerUp.Clone() as PowerUpConfig; } }

        public Library.ModelLibrary ModelLibrary { get; private set; }

        public Library.MenuLibrary MenuLibrary { get; private set; }

        public AMenuItem ActiveMenuItem
        {
            get { return (AMenuItem)(this.lpGridActive.SelectedItems.First() as ADisplayable).Clone(this.levelBuilder.Content); }
        }

        public ADisplayable InactiveMenuItem
        {
            get { return (this.lpGridInactive.SelectedItems.First() as ADisplayable).Clone(this.levelBuilder.Content); }
        }

        List<LibraryItem>[] configs;
        LevelBuilderControl levelBuilder;

        BackgroundItemConfig backgroundItem;
        PlatformConfig platform;
        PowerUpConfig powerUp;

        /// <summary>
        /// Initialize form with model library and defaults.
        /// </summary>
        /// <param name="levelBuilder"></param>
        public DefaultsForm(LevelBuilderControl levelBuilder)
        {
            this.levelBuilder = levelBuilder;
            InitializeComponent();
            this.backgroundItem = new BackgroundItemConfig() { Alpha = 1, NotTextured = false, ModelPath = "box", Transforms = new MatrixTransforms() { Translation = new Microsoft.Xna.Framework.Vector3(1, 1, -1), Scale = new Microsoft.Xna.Framework.Vector3(1, 1, 1) } };
            this.platform = new PlatformConfig(new MatrixTransforms()) { Height = 0.1f, Width = 1, ModelPath = "platform", Name = "platform" };
            this.powerUp = PowerUpConfig.Default(Microsoft.Xna.Framework.Vector3.Zero);

            this.propertyGrid1.SelectedObject = this.platform;
            this.propertyGrid2.SelectedObject = this.backgroundItem;
            this.propertyGrid3.SelectedObject = this.powerUp;
            Win32.SetWindowTheme(this.listViewModels.Handle, "explorer", null);
        }

        public void Show(int activeTab)
        {
            this.tabControlMain.SelectedIndex = activeTab;
            this.Show();
        }

        private void DefaultsForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            this.Hide();
        }

        private void DefaultsForm_Load(object sender, EventArgs e)
        {
            this.ModelLibrary = ModelLibrary.Load(true, this.levelBuilder.GraphicsDevice, this.levelBuilder.Content);
            this.MenuLibrary = new MenuLibrary(this.levelBuilder.Game.Content);
            this.configs = new List<LibraryItem>[] { ModelLibrary.Platforms, ModelLibrary.BackgroundItems, ModelLibrary.Powerups };
            this.comboBox1.SelectedIndex = 0;
            ResetPreview();
        }

        public void ResetPreview()
        {
            this.listViewModels.Items.Clear();
            this.imageList1.Images.Clear();
            this.imageList1.Images.Add(Properties.Resources._1328614391_question_red);
            FillGroup(this.listViewModels.Groups[0], ModelLibrary.Platforms);
            FillGroup(this.listViewModels.Groups[1], ModelLibrary.BackgroundItems);
            FillGroup(this.listViewModels.Groups[2], ModelLibrary.Powerups);

            this.lpGridActive.DataSource = this.MenuLibrary.ActiveItems;
            this.lpGridInactive.DataSource = this.MenuLibrary.InactiveItems;
        }

        private void FillGroup(ListViewGroup group, List<LibraryItem> list)
        {
            group.Items.Clear();
            foreach (var item in list)
            {
                this.AddToGroup(group, item);
            }
        }

        private void AddToGroup(ListViewGroup group, LibraryItem item)
        {
            int imageIndex = 0;
            if (item.PreviewImage != null)
            {
                imageIndex = imageList1.Images.Count;
                imageList1.Images.Add(item.PreviewImage);
            }
            else
            {
                imageIndex = 0;
            }
            var lvi = listViewModels.Items.Add(item.DisplayName, imageIndex);
            lvi.Group = group;
            lvi.Tag = item;
        }

        private void DefaultsForm_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Escape)
            {
                this.Hide();
            }
        }

        private void listViewModels_DoubleClick(object sender, EventArgs e)
        {
            if (listViewModels.SelectedItems.Count == 1)
            {
                var itm = listViewModels.SelectedItems[0];
                switch (itm.Group.Name)
                {
                    case "BackgroundItems":
                        this.BackgroundItem.ModelPath = (itm.Tag as LibraryItem).ContentPath;
                        break;

                    case "Platforms":
                        this.Platform.ModelPath = (itm.Tag as LibraryItem).ContentPath;
                        break;

                    case "Powerups":
                        this.PowerUp.ModelPath = (itm.Tag as LibraryItem).ContentPath;
                        break;
                }
            }
        }

        private void groupBoxImport_Enter(object sender, EventArgs e)
        {
            if (groupBoxImport.Height < 40)
            {
                groupBoxImport.Height = 200;
            }
        }

        private void groupBoxImport_Resize(object sender, EventArgs e)
        {
            this.textBoxContentPath.Width = groupBoxImport.Width - this.textBoxContentPath.Location.X - 10;
            this.textBoxPreviewPath.Width = this.textBoxContentPath.Width;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (ValidateDisplayName() && ValidateContentPath() && ValidatePreviewPath())
            {
                var ppp = from p in this.configs[this.comboBox1.SelectedIndex] where p.ContentPath.Equals(this.textBoxContentPath.Text, StringComparison.CurrentCultureIgnoreCase) select p;
                if (ppp.Count() > 0)
                {
                    return;
                }

                LibraryItem pic = new LibraryItem()
                {
                    ContentPath = this.textBoxContentPath.Text,
                    DisplayName = this.textBoxDisplayName.Text,
                    PreviewPath = this.textBoxPreviewPath.Text
                };
                this.ModelLibrary.LoadItemPreview(pic);

                this.configs[this.comboBox1.SelectedIndex].Add(pic);
                this.AddToGroup(this.listViewModels.Groups[this.comboBox1.SelectedIndex], pic);

                this.textBoxContentPath.Clear();
                this.textBoxDisplayName.Clear();
            }
        }

        private void textBoxContentPath_TextChanged(object sender, EventArgs e)
        {
            if (ValidateContentPath())
            {
                textBoxContentPath.BackColor = Color.White;
            }
            else
            {
                textBoxContentPath.BackColor = Color.Red;
            }
        }

        #region Vaidation

        private bool ValidateContentPath()
        {
            return File.Exists(Path.Combine("Content", textBoxContentPath.Text) + ".xnb");
        }

        private bool ValidatePreviewPath()
        {
            return textBoxPreviewPath.Text.Length == 0 || File.Exists(textBoxPreviewPath.Text);
        }

        private bool ValidateDisplayName()
        {
            return this.textBoxDisplayName.Text.Length > 2;
        }

        #endregion Vaidation

        private void textBoxPreviewPath_TextChanged(object sender, EventArgs e)
        {
            if (ValidatePreviewPath())
            {
                textBoxPreviewPath.BackColor = Color.White;
            }
            else
            {
                textBoxPreviewPath.BackColor = Color.Red;
            }
        }

        private void textBoxContentPath_DoubleClick(object sender, EventArgs e)
        {
            this.openFileDialog1.Filter = "XNA Content file (*.xnb)|*.xnb";
            this.openFileDialog1.Title = "Select content file";
            if (this.openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.textBoxContentPath.Text = ContentPathEditor.StripContentFolderPath(openFileDialog1.FileName);
            }
        }

        private void textBoxPreviewPath_DoubleClick(object sender, EventArgs e)
        {
            this.openFileDialog1.Filter = "Image Files (*.png; *.jpg; *.gif)|*.png;*.jpg;*.gif|All Files|*.*";
            this.openFileDialog1.Title = "Select preview file";
            if (this.openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.textBoxPreviewPath.Text = openFileDialog1.FileName.Replace(Environment.CurrentDirectory + "\\", "");
            }
        }

        private void textBoxDisplayName_TextChanged(object sender, EventArgs e)
        {
            if (ValidateDisplayName())
            {
                textBoxDisplayName.BackColor = Color.White;
            }
            else
            {
                textBoxDisplayName.BackColor = Color.Red;
            }
        }

        private void saveLibToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (var saveDialog = new SaveFileDialog())
            {
                saveDialog.Title = "Export Model Library";
                saveDialog.Filter = "XML Config|*.xml";
                if (saveDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    this.ModelLibrary.Save(saveDialog.FileName);
                }
            }
        }

        private void listViewModels_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Delete)
            {
                while (this.listViewModels.SelectedItems.Count > 0)
                {
                    var itm = this.listViewModels.SelectedItems[0];
                    listViewModels.Items.Remove(itm);
                    int i = 0;
                    for (; i < this.listViewModels.Groups.Count; i++)
                    {
                        if (listViewModels.Groups[i] == itm.Group)
                        {
                            break;
                        }
                        this.configs[i].Remove(itm.Tag as LibraryItem);
                    }
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (this.listViewModels.SelectedItems.Count == 1 && ValidateDisplayName() && ValidateContentPath() && ValidatePreviewPath())
            {
                LibraryItem pic = listViewModels.SelectedItems[0].Tag as LibraryItem;
                pic.ContentPath = this.textBoxContentPath.Text;
                pic.DisplayName = this.textBoxDisplayName.Text;
                pic.PreviewPath = this.textBoxPreviewPath.Text;
                listViewModels.SelectedItems[0].Text = pic.DisplayName;
                try
                {
                    pic.LoadImage();
                    imageList1.Images.Add(pic.PreviewImage);
                    this.listViewModels.SelectedItems[0].ImageIndex = imageList1.Images.Count - 1;
                }
                catch
                {
                    this.listViewModels.SelectedItems[0].ImageIndex = 0;
                }
            }
        }

        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.listViewModels.SelectedItems.Count == 1)
            {
                LibraryItem pic = listViewModels.SelectedItems[0].Tag as LibraryItem;
                this.textBoxContentPath.Text = pic.ContentPath;
                this.textBoxDisplayName.Text = pic.DisplayName;
                if (pic.PreviewPath != null)
                {
                    this.textBoxPreviewPath.Text = pic.PreviewPath;
                }
                else
                {
                    this.textBoxPreviewPath.Clear();
                }
            }
            else
            {
                this.textBoxContentPath.Clear();
                this.textBoxDisplayName.Clear();
                this.textBoxPreviewPath.Clear();
            }
        }
    }
}